/**
 * 智能体调度器
 * 负责管理和调度不同的子智能体，实现solo模式
 */
import { BaseAgent } from '../core/BaseAgent';
import { DetectiveAssistant } from '../agents/DetectiveAssistant';
import { ProfileAnalyzer } from '../agents/ProfileAnalyzer';
import * as fs from 'fs';
import * as path from 'path';

// 智能体配置接口
interface AgentConfig {
  id: string;
  name: string;
  description: string;
  type: string;
  capabilities: string[];
  params?: Record<string, any>;
}

// 任务请求接口
interface TaskRequest {
  taskId: string;
  taskType: string;
  agentId: string;
  input: Record<string, any>;
  priority?: 'high' | 'medium' | 'low';
  deadline?: string;
}

// 任务结果接口
interface TaskResult {
  taskId: string;
  agentId: string;
  success: boolean;
  result?: any;
  error?: string;
  timestamp: string;
  executionTime: number;
}

// 调度器配置接口
interface SchedulerConfig {
  maxConcurrentTasks: number;
  defaultTimeout: number;
  logLevel: 'debug' | 'info' | 'warn' | 'error';
}

export class AgentScheduler {
  private agents: Map<string, BaseAgent> = new Map();
  private agentConfigs: Map<string, AgentConfig> = new Map();
  private configPath: string;
  private config: SchedulerConfig = {
    maxConcurrentTasks: 3,
    defaultTimeout: 60000,
    logLevel: 'info'
  };
  private taskQueue: TaskRequest[] = [];
  private activeTasks: Map<string, Promise<TaskResult>> = new Map();
  private taskResults: Map<string, TaskResult> = new Map();

  /**
   * 构造函数
   * @param configPath 智能体配置文件路径
   */
  constructor(configPath: string = '../../config/agents-config.json') {
    this.configPath = path.resolve(__dirname, configPath);
    this.initialize();
  }

  /**
   * 初始化调度器
   */
  private async initialize(): Promise<void> {
    try {
      // 加载智能体配置
      await this.loadAgentConfigs();
      
      // 初始化智能体实例
      await this.initializeAgents();
      
      this.log('info', '智能体调度器初始化完成');
    } catch (error) {
      this.log('error', `调度器初始化失败: ${error instanceof Error ? error.message : String(error)}`);
      throw error;
    }
  }

  /**
   * 加载智能体配置
   */
  private async loadAgentConfigs(): Promise<void> {
    try {
      if (!fs.existsSync(this.configPath)) {
        throw new Error(`配置文件不存在: ${this.configPath}`);
      }

      const configData = fs.readFileSync(this.configPath, 'utf-8');
      const configs = JSON.parse(configData);
      
      if (Array.isArray(configs)) {
        configs.forEach(config => {
          this.agentConfigs.set(config.id, config);
          this.log('debug', `已加载智能体配置: ${config.id} - ${config.name}`);
        });
      } else {
        throw new Error('配置文件格式错误，应为智能体配置数组');
      }
    } catch (error) {
      this.log('error', `加载智能体配置失败: ${error instanceof Error ? error.message : String(error)}`);
      throw error;
    }
  }

  /**
   * 初始化智能体实例
   */
  private async initializeAgents(): Promise<void> {
    try {
      this.agentConfigs.forEach((config, agentId) => {
        let agent: BaseAgent;
        
        // 根据智能体类型创建实例
        switch (config.type) {
          case 'detective_assistant':
            agent = new DetectiveAssistant(config.params || {});
            break;
          case 'profile_analyzer':
            agent = new ProfileAnalyzer(config.params || {});
            break;
          default:
            throw new Error(`未知的智能体类型: ${config.type}`);
        }
        
        this.agents.set(agentId, agent);
        this.log('info', `已初始化智能体: ${config.id} - ${config.name}`);
      });
    } catch (error) {
      this.log('error', `初始化智能体实例失败: ${error instanceof Error ? error.message : String(error)}`);
      throw error;
    }
  }

  /**
   * 配置solo模式
   * @param config 调度器配置
   */
  public configureSoloMode(config: Partial<SchedulerConfig>): void {
    this.config = { ...this.config, ...config };
    this.log('info', '已配置solo模式:', this.config);
  }

  /**
   * 执行任务（solo模式）
   * @param request 任务请求
   * @returns 任务结果
   */
  public async executeTask(request: TaskRequest): Promise<TaskResult> {
    const startTime = Date.now();
    const taskId = request.taskId || `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    request.taskId = taskId;
    
    try {
      this.log('info', `开始执行任务: ${taskId} (智能体: ${request.agentId})`);
      
      // 检查智能体是否存在
      const agent = this.agents.get(request.agentId);
      if (!agent) {
        throw new Error(`智能体不存在: ${request.agentId}`);
      }
      
      // 检查智能体是否支持该任务类型
      const agentConfig = this.agentConfigs.get(request.agentId);
      if (agentConfig && !agentConfig.capabilities.includes(request.taskType)) {
        throw new Error(`智能体 ${request.agentId} 不支持任务类型: ${request.taskType}`);
      }
      
      // 执行任务
      const result = await agent.execute(request.input);
      
      const executionTime = Date.now() - startTime;
      const taskResult: TaskResult = {
        taskId,
        agentId: request.agentId,
        success: true,
        result,
        timestamp: new Date().toISOString(),
        executionTime
      };
      
      this.taskResults.set(taskId, taskResult);
      this.log('info', `任务执行完成: ${taskId} (耗时: ${executionTime}ms)`);
      
      return taskResult;
    } catch (error) {
      const executionTime = Date.now() - startTime;
      const taskResult: TaskResult = {
        taskId,
        agentId: request.agentId,
        success: false,
        error: error instanceof Error ? error.message : String(error),
        timestamp: new Date().toISOString(),
        executionTime
      };
      
      this.taskResults.set(taskId, taskResult);
      this.log('error', `任务执行失败: ${taskId} - ${taskResult.error}`);
      
      return taskResult;
    }
  }

  /**
   * 批量执行任务（队列模式）
   * @param requests 任务请求数组
   * @returns 任务结果数组
   */
  public async executeBatchTasks(requests: TaskRequest[]): Promise<TaskResult[]> {
    // 添加到任务队列
    this.taskQueue.push(...requests);
    
    const results: TaskResult[] = [];
    
    // 并发执行任务，受最大并发数限制
    while (this.taskQueue.length > 0 || this.activeTasks.size > 0) {
      // 执行可以启动的新任务
      while (this.taskQueue.length > 0 && this.activeTasks.size < this.config.maxConcurrentTasks) {
        const request = this.taskQueue.shift()!;
        const taskPromise = this.executeTask(request);
        
        this.activeTasks.set(request.taskId, taskPromise);
        
        taskPromise.finally(() => {
          this.activeTasks.delete(request.taskId);
        });
      }
      
      if (this.activeTasks.size > 0) {
        // 等待任一任务完成
        const completedTask = await Promise.race(this.activeTasks.values());
        results.push(completedTask);
      } else {
        break;
      }
    }
    
    return results;
  }

  /**
   * 获取所有可用的智能体
   * @returns 智能体配置数组
   */
  public getAvailableAgents(): AgentConfig[] {
    return Array.from(this.agentConfigs.values());
  }

  /**
   * 获取智能体信息
   * @param agentId 智能体ID
   * @returns 智能体配置
   */
  public getAgentInfo(agentId: string): AgentConfig | undefined {
    return this.agentConfigs.get(agentId);
  }

  /**
   * 获取任务结果
   * @param taskId 任务ID
   * @returns 任务结果
   */
  public getTaskResult(taskId: string): TaskResult | undefined {
    return this.taskResults.get(taskId);
  }

  /**
   * 获取当前系统状态
   * @returns 系统状态信息
   */
  public getSystemStatus(): {
    availableAgents: number;
    activeTasks: number;
    queuedTasks: number;
    completedTasks: number;
  } {
    return {
      availableAgents: this.agents.size,
      activeTasks: this.activeTasks.size,
      queuedTasks: this.taskQueue.length,
      completedTasks: this.taskResults.size
    };
  }

  /**
   * 重新加载智能体配置
   */
  public async reloadConfig(): Promise<void> {
    this.agents.clear();
    this.agentConfigs.clear();
    
    await this.initialize();
    this.log('info', '智能体配置已重新加载');
  }

  /**
   * 添加新的智能体配置
   * @param config 智能体配置
   */
  public async addAgentConfig(config: AgentConfig): Promise<void> {
    // 获取当前配置
    const currentConfigs = Array.from(this.agentConfigs.values());
    
    // 检查是否已存在
    if (this.agentConfigs.has(config.id)) {
      throw new Error(`智能体ID已存在: ${config.id}`);
    }
    
    // 添加新配置
    currentConfigs.push(config);
    
    // 保存到文件
    fs.writeFileSync(this.configPath, JSON.stringify(currentConfigs, null, 2), 'utf-8');
    
    // 重新加载配置
    await this.reloadConfig();
  }

  /**
   * 更新智能体配置
   * @param agentId 智能体ID
   * @param config 智能体配置
   */
  public async updateAgentConfig(agentId: string, config: Partial<AgentConfig>): Promise<void> {
    if (!this.agentConfigs.has(agentId)) {
      throw new Error(`智能体不存在: ${agentId}`);
    }
    
    // 获取当前配置
    const currentConfigs = Array.from(this.agentConfigs.values());
    
    // 更新配置
    const updatedConfigs = currentConfigs.map(c => 
      c.id === agentId ? { ...c, ...config, id: agentId } : c
    );
    
    // 保存到文件
    fs.writeFileSync(this.configPath, JSON.stringify(updatedConfigs, null, 2), 'utf-8');
    
    // 重新加载配置
    await this.reloadConfig();
  }

  /**
   * 删除智能体
   * @param agentId 智能体ID
   */
  public async removeAgent(agentId: string): Promise<void> {
    if (!this.agentConfigs.has(agentId)) {
      throw new Error(`智能体不存在: ${agentId}`);
    }
    
    // 获取当前配置
    const currentConfigs = Array.from(this.agentConfigs.values());
    
    // 过滤掉要删除的智能体
    const updatedConfigs = currentConfigs.filter(c => c.id !== agentId);
    
    // 保存到文件
    fs.writeFileSync(this.configPath, JSON.stringify(updatedConfigs, null, 2), 'utf-8');
    
    // 重新加载配置
    await this.reloadConfig();
  }

  /**
   * 记录日志
   * @param level 日志级别
   * @param message 日志消息
   * @param data 附加数据
   */
  private log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: any): void {
    const levelPriority: Record<string, number> = {
      'debug': 0,
      'info': 1,
      'warn': 2,
      'error': 3
    };
    
    if (levelPriority[level] >= levelPriority[this.config.logLevel]) {
      const timestamp = new Date().toISOString();
      console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}`, data || '');
    }
  }
}
